﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace TicTacToe
{
    public partial class Form1 : Form
    {
        public delegate void TicTacToeClick(int x, int y, TicTacToeValue value);
        private List<TicTacToeMove> moves = new List<TicTacToeMove>();
        private bool isXTurn = false;
        public bool IsXTurn
        {
            get
            {
                return this.isXTurn;
            }
            set
            {
                this.isXTurn = value;
                if (this.isXTurn)
                    this.trackBar1.Value = 0;
                else
                    this.trackBar1.Value = 1;
            }
        }
        private TicTacToeValue whoWon = TicTacToeValue.NONE;
        private int ticks = 0;
        private int movesTaken = 0;
        private TicTacToeValue[,] board = new TicTacToeValue[3, 3];
        public Form1()
        {
            InitializeComponent();
            this.timer1.Interval = 1000;
            this.timer1.Start();
            this.textBox1.Text = "00:00:00";
            this.progressBar1.Minimum = 0;
            this.progressBar1.Maximum = 900;
            this.progressBar1.Value = 0;
        }

        private void timer1_Tick(object sender, EventArgs e)
        {
            this.ticks++;
            int seconds = this.ticks;
            int minutes = seconds / 60;
            seconds %= 60;
            int hours = minutes / 60;
            minutes %= 60;
            this.textBox1.Text = ((hours < 10) ? "0" : "") + hours + ":" + ((minutes < 10) ? "0" : "") + minutes + ":" + ((seconds < 10) ? "0" : "") + seconds;
            
        }

        private void OnTicTacToeAdd(TicTacToeButton button)
        {
            if (this.movesTaken < 9 && this.grid[button.X, button.Y].Value == TicTacToeValue.NONE && this.whoWon == TicTacToeValue.NONE)
            {
                if (this.IsXTurn)
                    this.grid[button.X, button.Y].Value = TicTacToeValue.X;
                else
                    this.grid[button.X, button.Y].Value = TicTacToeValue.O;
                this.IsXTurn = !this.IsXTurn;
                this.movesTaken++;
                this.progressBar1.Value = this.movesTaken * 100;

                TicTacToeMove move = new TicTacToeMove();
                move.x = button.X + 1;
                move.y = button.Y + 1;
                move.val = button.Value;
                this.moves.Add(move);
                this.listBox1.Items.Clear();
                Object[] temp = new Object[this.moves.Count];
                int i = 0;
                foreach (TicTacToeMove t in this.moves)
                {
                    temp[i] = t;
                    i++;
                }
                this.listBox1.Items.AddRange(temp);
                this.ValidateBoard(button.X, button.Y);
            }
        }
        private void ResetBoard(object sender, EventArgs BLAH)
        {
            this.moves.Clear();
            this.listBox1.Items.Clear();
            this.movesTaken = 0;
            this.progressBar1.Value = 0;
            this.whoWon = TicTacToeValue.NONE;
            this.label1.Text = "Press a button to place your symbol";
            foreach (TicTacToeButton x in this.grid)
            {
                x.Value = TicTacToeValue.NONE;
            }
        }
        private void ValidateBoard(int x, int y)
        {
            List<int> sums = new List<int>();
            sums.Add(RowSum(x));
            sums.Add(ColSum(y));
            if (x == y)
            {
                sums.Add(DiagSum());
            }
            else if (2 == y + x)
            {
                sums.Add(AntiDiagSum());
            }
            if (sums.Contains(12))
            {
                this.whoWon = TicTacToeValue.X;
            }
            else if (sums.Contains(3))
            {
                this.whoWon = TicTacToeValue.O;
            }
            if (this.whoWon != TicTacToeValue.NONE)
            {
                
                this.label1.Location = new System.Drawing.Point(84, 4);
                this.label1.Text = "Game won by " + this.whoWon.ToString();
            }
        }

        private int RowSum(int x)
        {
            int ret = 0;
            for (int y = 0; y < 3; y++)
            {
                switch (this.grid[x, y].Value)
                {
                    case TicTacToeValue.O:
                        ret += 1;
                        break;
                    case TicTacToeValue.X:
                        ret += 4;
                        break;
                    case TicTacToeValue.NONE:
                        ret += 0;
                        break;
                }
            }
            return ret;
        }
        private int ColSum(int y)
        {
            int ret = 0;
            for (int x = 0; x < 3; x++)
            {
                switch (this.grid[x, y].Value)
                {
                    case TicTacToeValue.O:
                        ret += 1;
                        break;
                    case TicTacToeValue.X:
                        ret += 4;
                        break;
                    case TicTacToeValue.NONE:
                        ret += 0;
                        break;
                }
            }
            return ret;
        }
        private int DiagSum()
        {
            int ret = 0;
            for (int x = 0; x < 3; x++)
            {
                switch (this.grid[x, x].Value)
                {
                    case TicTacToeValue.O:
                        ret += 1;
                        break;
                    case TicTacToeValue.X:
                        ret += 4;
                        break;
                    case TicTacToeValue.NONE:
                        ret += 0;
                        break;
                }
            }
            return ret;
        }
        private int AntiDiagSum()
        {
            int ret = 0;
            for (int x = 0; x < 3; x++)
            {
                switch (this.grid[x, 2 - x].Value)
                {
                    case TicTacToeValue.O:
                        ret += 1;
                        break;
                    case TicTacToeValue.X:
                        ret += 4;
                        break;
                    case TicTacToeValue.NONE:
                        ret += 0;
                        break;
                }
            }
            return ret;
        }
    }
    public struct TicTacToeMove
    {
        public int x;
        public int y;
        public TicTacToeValue val;
        public override string ToString()
        {

            return val.ToString() + " at (" + this.x + ", " + this.y + ")";
        }
    }
    public enum TicTacToeValue
    {
        NONE, X, O
    }
}
